package com.sz.demo.strategy;

import com.sz.demo.constant.PromotionEnum;
import com.sz.demo.discount.DiscountStrategy;
import com.sz.demo.discount.NoDiscount;
import com.sz.demo.discount.PercentageDiscount;
import com.sz.demo.model.Fruit;
import com.sz.demo.entity.Strawberry;
import com.sz.demo.promotion.FullReductionPromotion;
import com.sz.demo.promotion.NoPromotion;
import com.sz.demo.promotion.Promotion;
import java.math.BigDecimal;
import java.util.*;

/**
 * 水果折扣 加 满减促销策略
 * 支持为所有水果类型设置不同的折扣，满减促销应用于所有商品的总价
 * @author Lenovo
 */
public class FruitDiscountWithPromotionPricingStrategy extends AbstractPricingStrategy {
    private static final DiscountStrategy DEFAULT_NO_DISCOUNT = new NoDiscount();

    /**
     * 存储不同水果类型的折扣策略
     */
    private Map<Class<? extends Fruit>, DiscountStrategy> fruitDiscountStrategies;

    /**
     * 统一的满减促销策略
     */
    private Promotion promotionStrategy;

    /**
     * 默认构造函数
     */
    public FruitDiscountWithPromotionPricingStrategy() {
        this.fruitDiscountStrategies = new HashMap<>();
        this.promotionStrategy = new FullReductionPromotion(PromotionEnum.FULL_100_REDUCE_10);
        
        // 默认对草莓应用8折折扣
        this.fruitDiscountStrategies.put(Strawberry.class, new PercentageDiscount(new BigDecimal(0.8)));
    }

    /**
     * 通过参数配置折扣和满减的构造函数
     * @param discountConfigurations 水果折扣配置列表，每个元素是一个包含水果类型和折扣策略的Map
     * @param promotion 满减促销策略
     */
    public FruitDiscountWithPromotionPricingStrategy(List<Map.Entry<Class<? extends Fruit>, PercentageDiscount>> discountConfigurations,
                                                  Promotion promotion) {
        this.fruitDiscountStrategies = new HashMap<>();
        this.promotionStrategy = promotion != null ? promotion : new NoPromotion();
        
        // 配置折扣策略
        if (discountConfigurations != null) {
            for (Map.Entry<Class<? extends Fruit>, PercentageDiscount> config : discountConfigurations) {
                this.fruitDiscountStrategies.put(config.getKey(), config.getValue());
            }
        }
    }

    @Override
    protected DiscountStrategy getDiscountStrategyFor(Fruit fruit) {
        // 根据水果的实际类型获取对应的折扣策略，如果没有则返回无折扣
        return fruitDiscountStrategies.getOrDefault(fruit.getClass(), DEFAULT_NO_DISCOUNT);
    }

    @Override
    protected BigDecimal applyPromotion(BigDecimal subtotal) {
        // 对所有商品的总价应用统一的满减促销策略
        return promotionStrategy.apply(subtotal);
    }
    
    /**
     * 为特定水果类型设置折扣策略
     */
    public void setDiscountStrategyFor(Class<? extends Fruit> fruitClass, DiscountStrategy discountStrategy) {
        this.fruitDiscountStrategies.put(fruitClass, discountStrategy);
    }
    
    /**
     * 为特定水果类型设置百分比折扣
     */
    public void setPercentageDiscountFor(Class<? extends Fruit> fruitClass, BigDecimal discountRate) {
        this.fruitDiscountStrategies.put(fruitClass, new PercentageDiscount(discountRate));
    }
}